package com.atguigu.tingshu.order.strategy.impl;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

import com.atguigu.tingshu.account.client.UserAccountFeignClient;
import com.atguigu.tingshu.common.constant.KafkaConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.common.service.KafkaService;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.order.OrderDerate;
import com.atguigu.tingshu.model.order.OrderDetail;
import com.atguigu.tingshu.model.order.OrderInfo;
import com.atguigu.tingshu.order.service.OrderDerateService;
import com.atguigu.tingshu.order.service.OrderDetailService;
import com.atguigu.tingshu.order.service.OrderInfoService;
import com.atguigu.tingshu.order.strategy.SaveOrderStrategy;
import com.atguigu.tingshu.vo.account.AccountLockResultVo;
import com.atguigu.tingshu.vo.account.AccountLockVo;
import com.atguigu.tingshu.vo.order.OrderDerateVo;
import com.atguigu.tingshu.vo.order.OrderDetailVo;
import com.atguigu.tingshu.vo.order.OrderInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

@Service
@Slf4j
public class AccountSaveOrderStrategy implements SaveOrderStrategy {

    @Autowired
    private UserAccountFeignClient userAccountFeignClient ;

    @Autowired
    private OrderInfoService orderInfoService ;

    @Autowired
    private OrderDetailService orderDetailService ;

    @Autowired
    private OrderDerateService orderDerateService ;

    @Autowired
    private KafkaService kafkaService ;

    @Transactional
    @Override
    public OrderInfoVo saveOrder(OrderInfoVo orderInfoVo) {

        // 获取当前登录的用户的id
        Long userId = AuthContextHolder.getUserId();

        // 调用account微服务的接口检查并锁定账户的可用金额
        AccountLockVo accountLockVo = new AccountLockVo() ;
        accountLockVo.setOrderNo(orderInfoVo.getTradeNo());
        accountLockVo.setUserId(userId);
        accountLockVo.setAmount(orderInfoVo.getOrderAmount());
        String content = orderInfoVo.getOrderDetailVoList().get(0).getItemName();
        accountLockVo.setContent(content);
        Result<AccountLockResultVo> accountLockResultVoResult = userAccountFeignClient.checkAndLock(accountLockVo);
        Integer code = accountLockResultVoResult.getCode();     // 获取业务状态码
        if(code.intValue() != 200) {        // 检查和锁定账户可用金额失败了
            throw new GuiguException(ResultCodeEnum.ACCOUNT_LESS) ;
        }

        try {

            // 保存订单的相关数据: order_info、order_detail、order_derate
            this.saveOrderInfoAndOrderDetailAndOrderDerate(orderInfoVo , orderInfoService , orderDetailService , orderDerateService);

        }catch (Exception e) {
            e.printStackTrace();

            // 发送解锁账户金额消息
            kafkaService.sendMsg(KafkaConstant.QUEUE_ACCOUNT_UNLOCK , orderInfoVo.getTradeNo());
            throw new GuiguException(ResultCodeEnum.SYSTEM_ERROR) ;
        }


        // 返回
        return orderInfoVo;
    }

    @Override
    public String getPayway() {
        return SystemConstant.ORDER_PAY_ACCOUNT;        // 余额支付 1103
    }

    @Override
    public void saveOrderAfterProcess(OrderInfoVo orderInfoVo) {
        orderInfoService.orderPaySuccess(orderInfoVo.getTradeNo()) ;              // 调用orderInfoService中的方法：1、修改订单的状态   2、向kafka中发送保存购买信息的消息
        kafkaService.sendMsg(KafkaConstant.QUEUE_ACCOUNT_MINUS , orderInfoVo.getTradeNo());     // 向kafka中发送扣减账户金额消息
    }
}
